/**
 * Copyright (c) Huawei Technologies Co., Ltd. 1987-2021. All rights reserved.
*/

package com.gitee.fufu669.utils;

import com.gitee.fufu669.common.CacheKeyCommon;
import com.gitee.fufu669.service.CacheService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author wangfupeng
 */
public class CacheAopUtil {

    /**
     * TODO
    */
    public static final Logger logger = LoggerFactory.getLogger(CacheAopUtil.class);

    /**
     * TODO
    */
    public static String getCacheKey(JoinPoint joinPoint, String[] parameterNames) {
        // TODO
        Object target = joinPoint.getTarget();
        /** 当前的类的全名*/
        String targetName = target.getClass().getName();
        // 字符串赋值
        String methodName = joinPoint.getSignature().getName();
        // TODO
        Object[] argumentsValues = joinPoint.getArgs();
        // TODO
        Signature signature = joinPoint.getSignature();
        // TODO
        MethodSignature methodSignature = (MethodSignature) signature;
        //2.最关键的一步:通过这获取到方法的所有参数名称的字符串数组
        String[] parameterNamesInMethod = methodSignature.getParameterNames();
        // 赋值
        String cacheKeyBefore = "";
        // 判断
        if (parameterNames.length == 0) {
            // 遍历
            for (int i = 0; i < argumentsValues.length; i++) {
                // 赋值
                Object argumentsValue = argumentsValues[i];
                // 尝试下面的代码
                try {
                    // 增加
                    cacheKeyBefore += CacheJsonUtil.toJson(argumentsValue);
                // 捕捉异常
                } catch (Exception e) {
                    logger.info("计算key时有对象无法序列化，如果有key生成则可以忽略。");
                    //e.printStackTrace();
                }
            }
        // 否则
        } else {
            // 遍历
            for (int h = 0; h < parameterNames.length; h++) {
                // 遍历
                for (int i = 0; i < parameterNamesInMethod.length; i++) {
                    // 判断
                    if (parameterNamesInMethod[i].equals(parameterNames[h])) {
                        // 赋值
                        Object argumentsValue = argumentsValues[i];
                        // 尝试下面的代码
                        try {
                            // 增加
                            cacheKeyBefore += CacheJsonUtil.toJson(argumentsValue);
                        // 捕捉异常
                        } catch (Exception e) {
                            logger.info("计算key时有对象无法序列化，如果有key生成则可以忽略。");
                        }
                        // 跳出
                        break;
                    }
                }
            }
        }
        // 赋值
        cacheKeyBefore = targetName + ":" + methodName + ":" + cacheKeyBefore;
        // 返回
        return "cachekey:" + CachePasswordUtil.sha256(cacheKeyBefore);
    }

    /**
     * TODO
    */
    public static String getCacheKey(JoinPoint joinPoint) {
        // TODO
        Object target = joinPoint.getTarget();
        /** 当前的类的全名*/
        String targetName = target.getClass().getName();
        // 字符串赋值
        String methodName = joinPoint.getSignature().getName();
        // TODO
        Object[] argumentsValues = joinPoint.getArgs();
        // TODO
        Signature signature = joinPoint.getSignature();
        // TODO
        MethodSignature methodSignature = (MethodSignature) signature;
        //2.最关键的一步:通过这获取到方法的所有参数名称的字符串数组
        String[] parameterNames = methodSignature.getParameterNames();
        // 赋值
        String cacheKeyBefore = "";
        // TODO
        cacheKeyBefore = getCacheKeyBeforeFromArgumentsValue(argumentsValues, cacheKeyBefore);
        // 赋值
        cacheKeyBefore = targetName + ":" + methodName + ":" + cacheKeyBefore;
        // 返回
        return "cachekey:" + CachePasswordUtil.sha256(cacheKeyBefore);
    }

    /**
     * TODO
    */
    public static String getCacheKeyBeforeFromArgumentsValue(Object[] argumentsValues, String cacheKeyBefore) {
        // 遍历
        for (int i = 0; i < argumentsValues.length; i++) {
            // 赋值
            Object argumentsValue = argumentsValues[i];
            // 尝试下面的代码
            try {
                // 增加
                cacheKeyBefore += CacheJsonUtil.toJson(argumentsValue);
            // 捕捉异常
            } catch (Exception e) {
                logger.info("计算key时有对象无法序列化，如果有key生成则可以忽略。");
                //e.printStackTrace();
            }
        }
        // 返回
        return cacheKeyBefore;
    }

    /**
     * TODO
    */
    public static boolean isRefreshFlag(int refreshSeconds, String cacheKey, CacheService cacheService) {
        // 定义
        boolean refreshFlag;
        // 判断
        if (refreshSeconds <= 0) {
            // 赋值
            refreshFlag = true;
        // 否则
        } else {
            /**判断如果刷新时间还没到，就禁止刷新。*/
            if (cacheService.lock(CacheKeyCommon.LOCK + "refresh:" + cacheKey, refreshSeconds)) {
                // 赋值
                refreshFlag = true;
            // 否则
            } else {
                // 赋值
                refreshFlag = false;
            }
        }
        // 返回
        return refreshFlag;
    }
}
